#include "Work.h"



Work::Work (Ptr< Document > pDoc, Ptr< ViewportControl > pViewportCtrl)
: _pDoc (pDoc), _pViewportCtrl (pViewportCtrl), _pSelectRegion (NULL), 
_isQuickMaskMode (false), _nextActionIndex (0), _hasSaved (true)
{
	_pViewportUI = new CanvasViewport (_pDoc, _pViewportCtrl);

	connect (_pViewportUI, SIGNAL (resized(QSize)), 
			_pViewportCtrl, SLOT (viewportResizeTo(QSize)));

	connect (_pViewportCtrl, SIGNAL (repaintViewport()), 
			_pViewportUI, SLOT (repaint()));

	connect (_pViewportUI, SIGNAL (painting(QPainter&)), 
			this, SLOT (handleCanvasPainting(QPainter&)));
}



Work::Work (Ptr< AbstractAction > pInitAction, Ptr< ViewportControl > pViewportCtrl)
: _pDoc (NULL), _pViewportCtrl (pViewportCtrl), _pSelectRegion (NULL), 
_isQuickMaskMode (false), _nextActionIndex (0), _hasSaved (true)
{
	_clear ();
	playAction (pInitAction);
	addActionRecord (pInitAction);
}



Work::~Work ()
{

}



void Work::handleCanvasPainting (QPainter & painter)
{
	if (_pSelectRegion != NULL)
	{
		// Draw selection border
		if (_isQuickMaskMode)
		{
			painter.drawImage (_pSelectRegion->getBounding ().topLeft (), 
				*(_pSelectRegion->getMaskDisplayImage ()));
		}
		else
		{
			painter.drawImage (_pSelectRegion->getBounding ().topLeft (), 
				*(_pSelectRegion->getBorderImage ()));
		}
	}
}



void Work::setQuickMaskMode (bool isQuickMaskMode)
{
	_isQuickMaskMode = isQuickMaskMode;
}



bool Work::isQuickMaskMode () const
{
	return _isQuickMaskMode;
}



Ptr< Document > Work::getDoc ()
{
	return _pDoc;
}



Ptr< SelectRegion > Work::getSelectRegion ()
{
	return _pSelectRegion;
}



void Work::setSelectRegion (Ptr< SelectRegion > pSelectRegion)
{
	_pSelectRegion = pSelectRegion;
}



Ptr< ViewportControl > Work::getViewportCtrl ()
{
	return _pViewportCtrl;
}



CanvasViewport * Work::getViewportUI ()
{
	return _pViewportUI;
}

void Work::save (const QString & filepath)
{
	Ptr< QImage > pImage = _pDoc->getCompositedImage ();
	if (!pImage->convertToFormat (_pDoc->getFormat ()).save (filepath))
		OOPTHROW (FormatNotSupportException);
	_hasSaved = true;
}

void Work::placeImage (const QString & filepath)
{
	Ptr< QImage > pImage = new QImage ();
	if (!pImage->load (filepath)) // Load fail
		OOPTHROW (FormatNotSupportException);

	_pDoc->addLayer (new Layer (
		filepath.mid (filepath.lastIndexOf ('/') + 1), new QImage (
		pImage->convertToFormat (_pDoc->getFormat ()).convertToFormat (
		QImage::Format_ARGB32))));
	_pDoc->refreshCompositedImage ();
	_pViewportUI->repaint ();
}

void Work::addActionRecord (Ptr< AbstractAction > pAction)
{
	if (_nextActionIndex < _actionRecordList.size ()) {
		_actionRecordList[_nextActionIndex] = pAction;
		_actionRecordList.resize (_nextActionIndex + 1);
	} else {
		_actionRecordList.push_back (pAction);
	}
	++_nextActionIndex;
}

void Work::undo ()
{
	if (_nextActionIndex >= 1) {
		--_nextActionIndex;
		_replay ();
	}
}

void Work::redo ()
{
	if (_nextActionIndex < _actionRecordList.size ()) {
		playAction (_actionRecordList[_nextActionIndex]);
		++_nextActionIndex;
	}
}

int Work::getNextActionIndex () const
{
	return _nextActionIndex;	
}

void Work::_replay ()
{
	_clear ();
	for (int i = 0; i < _nextActionIndex; ++i)
		playAction (_actionRecordList[i]);
}

void Work::playAction (Ptr< AbstractAction > pAction)
{
	pAction->startAction ();
	pAction->applyAction ();
	_pDoc->refreshCompositedImage ();
	_pViewportUI->repaint ();
	emit workUpdated ();
	_hasSaved = false;
}

bool Work::canUndo () const
{
	if (_nextActionIndex > 1)
		return true;
	return false;
}

bool Work::canRedo () const
{
	if (_nextActionIndex < _actionRecordList.size ())
		return true;
	return false;
}

void Work::_clear ()
{
	_pDoc = NULL;
	_pSelectRegion = NULL;
	_isQuickMaskMode = false;
	_hasSaved = true;
}
